package com.turtle3d.formallanguage;

import java.util.ArrayList;

import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.turtle.Turtle3D;
import com.turtle3d.util.Randomizer;
import com.turtle3d.visualizator.VisualData;

/**
 * TurtleController inteprets symbols and orders turtle to move accordingly.
 * 
 * @author Marek Paterczyk <marek.paterczyk@gmail.com>
 *
 */

public class TurtleController {
	private Turtle3D turtle3D;
	
	private VisualData visualData = new VisualData();		

	public TurtleController(Turtle3D turtle3D) {
		super();
		this.turtle3D = turtle3D;
	}
	
	public void interpretSymbol(Symbol symbol){												
		
		VisualSymbol visualSymbol = new VisualSymbol(symbol, turtle3D.getTransformMatrix(), turtle3D.getDepth());
		visualData.getVisualSequence().add(visualSymbol);
		
		String s = symbol.getSymbolName(); 
		if(s.equals("F") || s.equals("f")){
			turtle3D.forward(symbol.getParameter(Symbol.DISTANCE));					
		}
		else if(s.equals("+")){
			turtle3D.turn(symbol.getParameter(Symbol.TURN_ANGLE));
		}
		else if(s.equals("-")){
			turtle3D.turn(-symbol.getParameter(Symbol.TURN_ANGLE));
		}
		else if(s.equals("[")){
			turtle3D.push();			
		}
		else if(s.equals("]")){
			turtle3D.pop();
		}
		else if(s.equals("<")){
			turtle3D.roll(-symbol.getParameter(Symbol.ROLL_ANGLE));
		}
		else if(s.equals(">")){
			turtle3D.roll(symbol.getParameter(Symbol.ROLL_ANGLE));
		}
		else if(s.equals("R")){
			float variation = symbol.getParameter(Symbol.VARIATION);
			if(variation!=0)
				turtle3D.transform(Randomizer.getRandomizer().nextConeAngleTransformation(variation, true));
		}
		else if(s.equals("/")){
			turtle3D.pitch(symbol.getParameter(Symbol.PITCH_ANGLE));
		}
		else if(s.equals("\\")){
			turtle3D.pitch(-symbol.getParameter(Symbol.PITCH_ANGLE));
		}
		else if(s.equals("|")){
			turtle3D.turn(180);
		}
		else if(s.equals("S")){
			float scaleMultiplier = symbol.getParameter(Symbol.SCALE_MULTIPLIER);
			float scaleMultiplierX = symbol.parameterExists(Symbol.SCALE_MULTIPLIER_X)?symbol.getParameter(Symbol.SCALE_MULTIPLIER_X):scaleMultiplier;
			float scaleMultiplierY = symbol.parameterExists(Symbol.SCALE_MULTIPLIER_Y)?symbol.getParameter(Symbol.SCALE_MULTIPLIER_Y):scaleMultiplier;
			float scaleMultiplierZ = symbol.parameterExists(Symbol.SCALE_MULTIPLIER_Z)?symbol.getParameter(Symbol.SCALE_MULTIPLIER_Z):scaleMultiplier;
						
			turtle3D.scale(scaleMultiplierX, scaleMultiplierY, scaleMultiplierZ);
		}
		
	}
	
	public void interpretLSymbols(ArrayList<Symbol> symbols){
		for(Symbol s:symbols){
			interpretSymbol(s);
		}
				
		visualData.setMaximalDepthReached(turtle3D.getMaximalDepth());
	}

	public VisualData getVisualData()
	{
		return visualData;
	}
}
